package com.gewu.pm.ui.dialog;

import android.content.Context;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.gewu.pm.R;
import com.gewu.pm.aop.SingleClick;
import com.gewu.pm.app.AppAdapter;
import com.gewu.pm.manager.PickerLayoutManager;
import com.hjq.base.BaseDialog;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Locale;

/**
 * 自定义时间选择对话框
 */
public final class CustomTimeDialog {

    public static final class Builder
            extends BaseDialog.Builder<Builder>
            implements PickerLayoutManager.OnPickerListener {

        private final int mStartYear;

        private final TextView mCancelView;
        private final TextView mConfirmView;
        private final TextView mStartTimeView;
        private final TextView mEndTimeView;

        private final RecyclerView mYearView;
        private final RecyclerView mMonthView;
        private final RecyclerView mDayView;

        private final PickerLayoutManager mYearManager;
        private final PickerLayoutManager mMonthManager;
        private final PickerLayoutManager mDayManager;

        private final PickerAdapter mYearAdapter;
        private final PickerAdapter mMonthAdapter;
        private final PickerAdapter mDayAdapter;

        private OnListener mListener;

        // 当前选择的是开始时间还是结束时间
        private boolean mIsSelectingStartTime = true;

        // 开始时间
        private int mSelectedStartYear = 0;
        private int mSelectedStartMonth = 0;
        private int mSelectedStartDay = 0;

        // 结束时间
        private int mSelectedEndYear = 0;
        private int mSelectedEndMonth = 0;
        private int mSelectedEndDay = 0;

        public Builder(Context context) {
            this(context, Calendar.getInstance(Locale.CHINA).get(Calendar.YEAR) - 10);//默认今年往前10年
        }

        public Builder(Context context, int startYear) {
            this(context, startYear, Calendar.getInstance(Locale.CHINA).get(Calendar.YEAR) + 1);//默认今年往后1年
        }
        //startYear 开始时间  今年往前几年
        //endYear   结束时间  今年往后几年
        public Builder(Context context, int startYear, int endYear) {
            super(context);
            mStartYear = startYear;

            setContentView(R.layout.custom_time_dialog);
            setGravity(Gravity.BOTTOM);
            setAnimStyle(BaseDialog.ANIM_BOTTOM);
            setWidth(WindowManager.LayoutParams.MATCH_PARENT);

            mCancelView = findViewById(R.id.tv_custom_time_cancel);
            mConfirmView = findViewById(R.id.tv_custom_time_confirm);
            mStartTimeView = findViewById(R.id.tv_start_time);
            mEndTimeView = findViewById(R.id.tv_end_time);

            mYearView = findViewById(R.id.rv_custom_time_year);
            mMonthView = findViewById(R.id.rv_custom_time_month);
            mDayView = findViewById(R.id.rv_custom_time_day);

            mYearAdapter = new PickerAdapter(context);
            mMonthAdapter = new PickerAdapter(context);
            mDayAdapter = new PickerAdapter(context);

            // 生成年份
            ArrayList<String> yearData = new ArrayList<>(10);
            for (int i = mStartYear; i <= endYear; i++) {
                yearData.add(i + " " + getString(R.string.common_year));
            }

            // 生成月份
            ArrayList<String> monthData = new ArrayList<>(12);
            for (int i = 1; i <= 12; i++) {
                monthData.add(i + " " + getString(R.string.common_month));
            }

            Calendar calendar = Calendar.getInstance(Locale.CHINA);

            int day = calendar.getActualMaximum(Calendar.DATE);
            // 生成天数
            ArrayList<String> dayData = new ArrayList<>(day);
            for (int i = 1; i <= day; i++) {
                dayData.add(i + " " + getString(R.string.common_day));
            }

            mYearAdapter.setData(yearData);
            mMonthAdapter.setData(monthData);
            mDayAdapter.setData(dayData);

            mYearManager = new PickerLayoutManager.Builder(context)
                    .build();
            mMonthManager = new PickerLayoutManager.Builder(context)
                    .build();
            mDayManager = new PickerLayoutManager.Builder(context)
                    .build();

            mYearView.setLayoutManager(mYearManager);
            mMonthView.setLayoutManager(mMonthManager);
            mDayView.setLayoutManager(mDayManager);

            mYearView.setAdapter(mYearAdapter);
            mMonthView.setAdapter(mMonthAdapter);
            mDayView.setAdapter(mDayAdapter);

            // 默认设置为当前日期
            setYear(calendar.get(Calendar.YEAR));
            setMonth(calendar.get(Calendar.MONTH) + 1);
            setDay(calendar.get(Calendar.DAY_OF_MONTH));

            mYearManager.setOnPickerListener(this);
            mMonthManager.setOnPickerListener(this);

            setOnClickListener(mCancelView, mConfirmView, mStartTimeView, mEndTimeView);

            // 更新按钮样式
            updateButtonStyle();
        }

        public Builder setListener(OnListener listener) {
            mListener = listener;
            return this;
        }

        private Builder setYear(int year) {
            int index = year - mStartYear;
            if (index < 0) {
                index = 0;
            } else if (index > mYearAdapter.getItemCount() - 1) {
                index = mYearAdapter.getItemCount() - 1;
            }
            mYearView.scrollToPosition(index);
            onPicked(mYearView, index);
            return this;
        }

        private Builder setMonth(int month) {
            int index = month - 1;
            if (index < 0) {
                index = 0;
            } else if (index > mMonthAdapter.getItemCount() - 1) {
                index = mMonthAdapter.getItemCount() - 1;
            }
            mMonthView.scrollToPosition(index);
            onPicked(mMonthView, index);
            return this;
        }

        private Builder setDay(int day) {
            int index = day - 1;
            if (index < 0) {
                index = 0;
            } else if (index > mDayAdapter.getItemCount() - 1) {
                index = mDayAdapter.getItemCount() - 1;
            }
            mDayView.scrollToPosition(index);
            onPicked(mDayView, index);
            return this;
        }

        /**
         * 更新按钮样式
         */
        private void updateButtonStyle() {
            if (mIsSelectingStartTime) {
                mStartTimeView.setSelected(true);
                mEndTimeView.setSelected(false);
            } else {
                mStartTimeView.setSelected(false);
                mEndTimeView.setSelected(true);
            }
        }

        /**
         * 保存当前选择的时间
         */
        private void saveCurrentTime() {
            int year = mStartYear + mYearManager.getPickedPosition();
            int month = mMonthManager.getPickedPosition() + 1;
            int day = mDayManager.getPickedPosition() + 1;

            if (mIsSelectingStartTime) {
                mSelectedStartYear = year;
                mSelectedStartMonth = month;
                mSelectedStartDay = day;
                mStartTimeView.setText(year + "-" + String.format("%02d", month) + "-" + String.format("%02d", day));
            } else {
                mSelectedEndYear = year;
                mSelectedEndMonth = month;
                mSelectedEndDay = day;
                mEndTimeView.setText(year + "-" + String.format("%02d", month) + "-" + String.format("%02d", day));
            }
        }

        /**
         * 加载保存的时间
         */
        private void loadSavedTime() {
            if (mIsSelectingStartTime && mSelectedStartYear > 0) {
                setYear(mSelectedStartYear);
                setMonth(mSelectedStartMonth);
                setDay(mSelectedStartDay);
            } else if (!mIsSelectingStartTime && mSelectedEndYear > 0) {
                setYear(mSelectedEndYear);
                setMonth(mSelectedEndMonth);
                setDay(mSelectedEndDay);
            }
        }

        /**
         * {@link PickerLayoutManager.OnPickerListener}
         *
         * @param recyclerView              RecyclerView 对象
         * @param position                  当前滚动的位置
         */
        @Override
        public void onPicked(RecyclerView recyclerView, int position) {
            // 获取这个月最多有多少天
            Calendar calendar = Calendar.getInstance(Locale.CHINA);
            calendar.set(mStartYear + mYearManager.getPickedPosition(), mMonthManager.getPickedPosition(), 1);

            int day = calendar.getActualMaximum(Calendar.DATE);
            if (mDayAdapter.getItemCount() != day) {
                ArrayList<String> dayData = new ArrayList<>(day);
                for (int i = 1; i <= day; i++) {
                    dayData.add(i + " " + getString(R.string.common_day));
                }
                mDayAdapter.setData(dayData);
            }
        }

        @SingleClick
        @Override
        public void onClick(View view) {
            int viewId = view.getId();
            if (viewId == R.id.tv_custom_time_confirm) {
                // 保存当前选择的时间
                saveCurrentTime();

                // 校验时间
                if (mSelectedStartYear == 0 || mSelectedEndYear == 0) {
                    Toast.makeText(getContext(), "请选择开始时间和结束时间", Toast.LENGTH_SHORT).show();
                    return;
                }

                // 将日期转换为时间戳进行比较
                Calendar startCal = Calendar.getInstance();
                startCal.set(mSelectedStartYear, mSelectedStartMonth - 1, mSelectedStartDay, 0, 0, 0);
                startCal.set(Calendar.MILLISECOND, 0);

                Calendar endCal = Calendar.getInstance();
                endCal.set(mSelectedEndYear, mSelectedEndMonth - 1, mSelectedEndDay, 0, 0, 0);
                endCal.set(Calendar.MILLISECOND, 0);

                if (endCal.getTimeInMillis() < startCal.getTimeInMillis()) {
                    Toast.makeText(getContext(), "结束时间不能早于开始时间", Toast.LENGTH_SHORT).show();
                    return;
                }

                dismiss();
                if (mListener != null) {
                    mListener.onSelected(getDialog(), 
                        mSelectedStartYear, mSelectedStartMonth, mSelectedStartDay,
                        mSelectedEndYear, mSelectedEndMonth, mSelectedEndDay);
                }
            } else if (viewId == R.id.tv_custom_time_cancel) {
                dismiss();
                if (mListener != null) {
                    mListener.onCancel(getDialog());
                }
            } else if (viewId == R.id.tv_start_time) {
                if (!mIsSelectingStartTime) {
                    // 保存当前结束时间
                    saveCurrentTime();
                    // 切换到开始时间
                    mIsSelectingStartTime = true;
                    updateButtonStyle();
                    // 加载开始时间
                    loadSavedTime();
                }
            } else if (viewId == R.id.tv_end_time) {
                if (mIsSelectingStartTime) {
                    // 保存当前开始时间
                    saveCurrentTime();
                    // 切换到结束时间
                    mIsSelectingStartTime = false;
                    updateButtonStyle();
                    // 加载结束时间
                    loadSavedTime();
                }
            }
        }

        private static final class PickerAdapter extends AppAdapter<String> {

            private PickerAdapter(Context context) {
                super(context);
            }

            @NonNull
            @Override
            public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                return new ViewHolder();
            }

            private final class ViewHolder extends AppAdapter<?>.ViewHolder {

                private final TextView mPickerView;

                ViewHolder() {
                    super(R.layout.picker_item);
                    mPickerView = (TextView) findViewById(R.id.tv_picker_name);
                }

                @Override
                public void onBindView(int position) {
                    mPickerView.setText(getItem(position));
                }
            }
        }
    }

    public interface OnListener {

        /**
         * 选择完日期后回调
         *
         * @param startYear         开始年
         * @param startMonth        开始月
         * @param startDay          开始日
         * @param endYear           结束年
         * @param endMonth          结束月
         * @param endDay            结束日
         */
        void onSelected(BaseDialog dialog, int startYear, int startMonth, int startDay,
                       int endYear, int endMonth, int endDay);

        /**
         * 点击取消时回调
         */
        default void onCancel(BaseDialog dialog) {}
    }
}

